package com.multi.tool.java8function;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.websocket.Session;

@RestController
@Slf4j
@RequestMapping("/test")
public class TestLocksController {
    @Autowired
    Locks locks;

    @GetMapping("/supplier")
    public String supplier() {
        return locks.supplier("supplier", () -> {
            log.info("supplier =>>>>>>>>");
            return "supplier";
        });
    }

    @GetMapping("/consumer")
    public void consumer(Session session) {
        locks.consumer("consumer", session, (x) -> {
            log.info("consumer =>>>>>>>>session:{}", session);
        });
    }

    @GetMapping("/predicate")
    public Boolean predicate(Session session) {
        return locks.predicate("predicate", session, (x) -> {
            log.info("predicate =>>>>>>>>session:{}", session);
            return true;
        });
    }

    @GetMapping("/function")
    public Session function(Session session) {
        return locks.function("function", session, (x) -> {
            log.info("function =>>>>>>>>session:{}", session);
            return session;
        });
    }

    /**
     * 如果需要控制事务：
     */
    @GetMapping("/function_t")
    public Session functionT(Session session) {
        return locks.function("functionT", session, (x) ->
                locks.functionInTransaction(session, fun -> {
                    log.info("functionT =>>>>>>>>session:{}", session);
                    return session;
                }));
    }

    /**
     * locks下的所有方法都不是互斥的，方法是可以随意组合嵌套的，
     * function下可以使用predicate或者其他方法 或
     * predicateTransaction等其Transaction方法，例如：
     */
    @GetMapping("/consumerIn_t")
    public String consumerInTransaction() {
        return locks.supplier("consumerIn_t", () -> {
            locks.consumerInTransaction("consumerIn_t", (x) -> {
                log.info("运行事务方法 =>>>>>>>>");
            });
            return "consumerIn_t";
        });
    }
}
